﻿#pragma once

#include "../MirControls/MirLabel.h"
#include "UserObject.h"
#include "../../Shared/Enums.h"
#include "PlayerObject.h"
#include "Effect.h"
#include "../MirGraphics/MLibrary.h"
#include "Damage.h"
#include <string>
#include <vector>
#include <algorithm>
#include <optional>
#include "../../stringhelper.h"

using namespace Client::MirControls;
using namespace Client::MirGraphics;
using namespace Client::MirScenes;
using namespace Client::MirSounds;
using namespace Client::MirScenes::Dialogs;
using namespace SlimDX;

namespace Client::MirObjects
{
    class MapObject
    {
    public:
        static Font *ChatFont;
        static std::vector<MirLabel*> LabelList;

        static UserObject *User;
        static MapObject *MouseObject;
        static MapObject *TargetObject;
        static MapObject *MagicObject;
        virtual ObjectType getRace() const = 0;
        virtual bool getBlocking() const = 0;

        unsigned int ObjectID = 0;
        std::string Name = std::string::Empty;
        Point *CurrentLocation, *MapLocation;
        MirDirection Direction = static_cast<MirDirection>(0);
        bool Dead = false, Hidden = false, SitDown = false, Sneaking = false;
        PoisonType Poison = static_cast<PoisonType>(0);
        long long DeadTime = 0;
        unsigned char AI = 0;
        bool InTrapRock = false;
        int JumpDistance = 0;

        bool Blend = true;

        long long BlindTime = 0;
        unsigned char BlindCount = 0;

        unsigned char PercentHealth = 0;
        long long HealthTime = 0;

        std::vector<QueuedAction*> ActionFeed = std::vector<QueuedAction*>();
        virtual ~MapObject()
        {
            delete CurrentLocation;
            delete MapLocation;
            delete BodyLibrary;
            delete DrawColour;
            delete NameColour;
            delete LightColour;
            delete NameLabel;
            delete ChatLabel;
            delete GuildLabel;
            delete DrawLocation;
            delete Movement;
            delete FinalDrawLocation;
            delete OffSetMove;
            delete DisplayRectangle;
            delete TempLabel;
        }

        QueuedAction *getNextAction() const;

        std::vector<Effect*> Effects;
        std::vector<BuffType> Buffs;

        MLibrary *BodyLibrary;
        Color *DrawColour = Color::White, *NameColour = Color::White, *LightColour = Color::White;
        MirLabel *NameLabel, *ChatLabel, *GuildLabel;
        long long ChatTime = 0;
        int DrawFrame = 0, DrawWingFrame = 0;
        Point *DrawLocation, *Movement, *FinalDrawLocation, *OffSetMove;
        Rectangle *DisplayRectangle;
        int Light = 0, DrawY = 0;
        long long NextMotion = 0, NextMotion2 = 0;
        MirAction CurrentAction = static_cast<MirAction>(0);
        bool SkipFrames = false;

        //Sound
        int StruckWeapon = 0;

        MirLabel *TempLabel;

        static std::vector<MirLabel*> DamageLabelList;
        std::vector<Damage*> Damages;

    protected:
        Point *getGlobalDisplayLocationOffset() const;

        MapObject(unsigned int objectID);
    public:
        void Remove();

        virtual void Process() = 0;
        virtual void Draw() = 0;
        virtual bool MouseOver(Point *p) = 0;

        void AddBuffEffect(BuffType type);
        void RemoveBuffEffect(BuffType type);

        virtual Missile *CreateProjectile(int baseIndex, MLibrary *library, bool blend, int count, int interval, int skip, int lightDistance = 6, bool direction16 = true, std::optional<Color*> &lightColour = std::nullopt, unsigned int targetID = 0);

        void Chat(const std::string &text);
        virtual void DrawChat();

        virtual void CreateLabel();
        virtual void DrawName();
        virtual void DrawBlend();
        void DrawDamages();
        void DrawHealth();

        void DrawPoison();

        virtual void DrawBehindEffects(bool effectsEnabled) = 0;

        virtual void DrawEffects(bool effectsEnabled) = 0;

    };

}
